libxl: write IO ABI for disk frontends
authorWei Liu <wei.liu2@citrix.com>
Fri, 26 Apr 2013 10:11:37 +0000 (11:11 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 26 Apr 2013 14:55:10 +0000 (15:55 +0100)
This is a patch to forward-port a Xend behaviour. Xend writes IO ABI used for
all frontends. Blkfront before 2.6.26 relies on this behaviour otherwise guest
cannot boot when running in 32-on-64 mode. Blkfront after 2.6.26 writes that
node itself, in which case it's just an overwrite to an existing node which
should be OK.

In fact Xend writes the ABI for all frontends including console and vif. But
nowadays only old disk frontends rely on that behaviour so that we only write
the ABI for disk frontends in libxl, minimizing the impact.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
tools/libxc/xc_dom_arm.c
tools/libxc/xc_dom_x86.c
tools/libxc/xenctrl.h
tools/libxl/libxl.c

index 041832e68e7e168a42b3f6bbc534debcd31bf5b5..aaf35ca70dc68a475e61accaadd7912a941da44c 100644 (file)
 #define CONSOLE_PFN_OFFSET 0
 #define XENSTORE_PFN_OFFSET 1
 
+/* get guest IO ABI protocol */
+const char *xc_domain_get_native_protocol(xc_interface *xch,
+                                          uint32_t domid)
+{
+    return XEN_IO_PROTO_ABI_ARM;
+}
+
 /* ------------------------------------------------------------------------ */
 /*
  * arm guests are hybrid and start off with paging disabled, therefore no
index d89526d78937eb49e5997cdb3b2b2662171a3b07..f1be43bed67ba1da900a1f7907d181f7eac6a21c 100644 (file)
 #define round_down(addr, mask)   ((addr) & ~(mask))
 #define round_up(addr, mask)     ((addr) | (mask))
 
+/* get guest IO ABI protocol */
+const char *xc_domain_get_native_protocol(xc_interface *xch,
+                                          uint32_t domid)
+{
+    int ret;
+    uint32_t guest_width;
+    const char *protocol;
+    DECLARE_DOMCTL;
+
+    memset(&domctl, 0, sizeof(domctl));
+    domctl.domain = domid;
+    domctl.cmd = XEN_DOMCTL_get_address_size;
+
+    ret = do_domctl(xch, &domctl);
+
+    if ( ret )
+        return NULL;
+
+    guest_width = domctl.u.address_size.size;
+
+    switch (guest_width) {
+    case 32: /* 32 bit guest */
+        protocol = XEN_IO_PROTO_ABI_X86_32;
+        break;
+    case 64: /* 64 bit guest */
+        protocol = XEN_IO_PROTO_ABI_X86_64;
+        break;
+    default:
+        protocol = NULL;
+    }
+
+    return protocol;
+}
+
 static unsigned long
 nr_page_tables(struct xc_dom_image *dom,
                xen_vaddr_t start, xen_vaddr_t end, unsigned long bits)
index 54a2d5aff54bfca95fb04ec0ddfbc9385e6149d9..c024af439b601f22bebfa5e7c54af60f495fc78b 100644 (file)
@@ -671,6 +671,16 @@ int xc_domain_hvm_setcontext(xc_interface *xch,
                              uint8_t *hvm_ctxt,
                              uint32_t size);
 
+/**
+ * This function will return guest IO ABI protocol
+ *
+ * @parm xch a handle to an open hypervisor interface
+ * @parm domid the domain to get IO ABI protocol for
+ * @return guest protocol on success, NULL on failure
+ */
+const char *xc_domain_get_native_protocol(xc_interface *xch,
+                                          uint32_t domid);
+
 /**
  * This function returns information about the execution context of a
  * particular vcpu of a domain.
index 0f936c0ab77444593f959916cd5085eed5755b44..30302c71b09a536b8654e61f69266c747252b0a5 100644 (file)
@@ -2052,6 +2052,12 @@ static void device_disk_add(libxl__egc *egc, uint32_t domid,
     libxl_ctx *ctx = gc->owner;
     xs_transaction_t t = XBT_NULL;
 
+    libxl_domain_type type = libxl__domain_type(gc, domid);
+    if (type == LIBXL_DOMAIN_TYPE_INVALID) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
     for (;;) {
         rc = libxl__xs_transaction_start(gc, &t);
         if (rc) goto out;
@@ -2170,6 +2176,23 @@ static void device_disk_add(libxl__egc *egc, uint32_t domid,
         flexarray_append(front, "device-type");
         flexarray_append(front, disk->is_cdrom ? "cdrom" : "disk");
 
+        /*
+         * Old PV kernel disk frontends before 2.6.26 rely on tool stack to
+         * write disk native protocol to frontend node. Xend does this, port
+         * this behaviour to xl.
+         *
+         * New kernels write this node themselves. In that case it just
+         * overwrites an existing node which is OK.
+         */
+        if (type == LIBXL_DOMAIN_TYPE_PV) {
+            const char *protocol =
+                xc_domain_get_native_protocol(ctx->xch, domid);
+            if (protocol) {
+                flexarray_append(front, "protocol");
+                flexarray_append(front, libxl__strdup(gc, protocol));
+            }
+        }
+
         libxl__device_generic_add(gc, t, device,
                             libxl__xs_kvs_of_flexarray(gc, back, back->count),
                             libxl__xs_kvs_of_flexarray(gc, front, front->count));